package bean;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Cascade;

import bean.vo.ItemListaPreciosVO;
import bean.vo.ListaPreciosVO;

@Entity 
@Table( name = "listas_de_precios" )
@SuppressWarnings({"unchecked"})
public class ListaPrecios extends EntidadPersistente{
	@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH} )
	@Cascade( org.hibernate.annotations.CascadeType.SAVE_UPDATE)
	private Proveedor proveedor;
	private Integer numeroLista;
	private Integer numeroListaReemplazada;
	@Temporal(TemporalType.DATE)
	private Date fechaEmision;
	@Temporal(TemporalType.DATE)
	private Date fechaCaducidad;
	@OneToMany (cascade = CascadeType.ALL, mappedBy = "listaPrecio")
	private List<ItemListaPrecios> itemsListaPrecio;
	private boolean activa;
	private boolean listaDeOfertas;
	
	public ListaPrecios () {
		this.itemsListaPrecio = new ArrayList<ItemListaPrecios>();
	}
	
	public ListaPrecios (Proveedor proveedor, Integer numeroLista) {
		this();
		this.proveedor = proveedor;
		this.numeroLista = numeroLista;
	}

	public ListaPrecios (Proveedor proveedor, Integer numeroLista, Date fechaEmision, Date fechaCaducidad, boolean esListaDeOfertas) throws Exception {
		this(proveedor, numeroLista);
		
		if (numeroLista == null || fechaEmision == null || fechaCaducidad == null) {
			throw new Exception("ERROR - Numero de lista, fecha de emision y fecha de caducidad son requeridos.");
		}
		this.fechaEmision = fechaEmision;
		this.fechaCaducidad = fechaCaducidad;
		this.activa = true;
		this.listaDeOfertas = esListaDeOfertas;
	}
	
	public ListaPreciosVO getVO() {
		ListaPreciosVO vo = new ListaPreciosVO();
		vo.setActiva(activa);
		vo.setFechaCaducidad(fechaCaducidad);
		vo.setFechaEmision(fechaEmision);
		vo.setItemsListaPrecio(new VOList<ItemListaPreciosVO>().getVoList(itemsListaPrecio));
		vo.setNumeroListaReemplazada(numeroListaReemplazada);
		
		return vo;
	}
	
	public boolean isActiva() {
		return activa;
	}

	public boolean isListaDeOfertas() {
		return listaDeOfertas;
	}

	public void setListaDeOfertas(boolean listaDeOfertas) {
		this.listaDeOfertas = listaDeOfertas;
	}

	public void setActiva(boolean activa) {
		this.activa = activa;
	}
	
	public Proveedor getProveedor() {
		return proveedor;
	}
	
	public void setProveedor(Proveedor proveedor) {
		this.proveedor = proveedor;
	}
	
	public Integer getNumeroLista() {
		return numeroLista;
	}
	
	public void setNumeroLista(Integer numeroLista) {
		this.numeroLista = numeroLista;
	}
	
	public Date getFechaEmision() {
		return fechaEmision;
	}
	
	public void setFechaEmision(Date fechaEmision) {
		this.fechaEmision = fechaEmision;
	}
	
	public Date getFechaCaducidad() {
		return fechaCaducidad;
	}
	
	public void setFechaCaducidad(Date fechaCaducidad) {
		this.fechaCaducidad = fechaCaducidad;
	}

	public List<ItemListaPrecios> getItemsListaPrecio() {
		return itemsListaPrecio;
	}
	
	public void setItemsListaPrecio(List<ItemListaPrecios> itemsListaPrecio) {
		this.itemsListaPrecio = itemsListaPrecio;
	}
	
	public void agregarItem(Producto producto, Float precio, Integer cantidadMinima)
	{
		ItemListaPrecios item = new ItemListaPrecios(this, producto, precio);
		if (!itemsListaPrecio.contains(item))
		{
			itemsListaPrecio.add(item);
			if(cantidadMinima != null && isListaDeOfertas())
			{
				//Solo las listas de ofertas pueden tener cantidad minima a comprar
				item.setCantidadMinima(cantidadMinima);
			}
		}
	}
	
	public void eliminarItem(Producto producto)
	{
		ItemListaPrecios item = new ItemListaPrecios(this, producto, 0);
		if (itemsListaPrecio.contains(item))
		{
			itemsListaPrecio.remove(item);
		}
	}
	
	@Override
	public int hashCode() {
		final int primo = 31;
		int result = 1;
		result = primo * (result + (proveedor == null ? 0 : proveedor.hashCode()) + (numeroLista == null ? 0 : numeroLista.hashCode()) );
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) return true;	
		if ((obj == null) || (!(obj instanceof ListaPrecios))) {
			return false;
		}
		
		ListaPrecios otro = (ListaPrecios) obj;
		
		boolean mismoProveedor = (proveedor!=null && otro.proveedor != null ? (proveedor.equals(otro.proveedor)) : false);
		boolean mismoNumero = (numeroLista!=null && otro.numeroLista != null ? (numeroLista.equals(otro.numeroLista)) : false);
		
		return mismoProveedor && mismoNumero;
	}

	public Integer getNumeroListaReemplazada() {
		return numeroListaReemplazada;
	}

	public void setNumeroListaReemplazada(Integer numeroListaReemplazada) {
		this.numeroListaReemplazada = numeroListaReemplazada;
	}
}
